package com.dingmouren.layoutmanagergroup.echelon;

import android.content.Context;
import android.graphics.PointF;
import android.os.CountDownTimer;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.LinearSmoothScroller;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;

import java.util.ArrayList;

/**
 * Created by 钉某人
 * github: https://github.com/DingMouRen
 * email: naildingmouren@gmail.com
 */

public class EchelonLayoutManager extends LinearLayoutManager {

    private static final String tag = "EchelonLayoutManager";
    private boolean showLog = false;
    private Context mContext;
    private int mItemViewWidth;
    public static int mItemViewHeight;
    public static int mItemCount;
    private int mScrollOffset = Integer.MAX_VALUE;
    private float mScale = 0.9f;

    public EchelonLayoutManager(Context context) {
        super(context);
        this.mContext = context;
        mItemViewWidth = (int) (getHorizontalSpace() * 0.87f);//item的宽
        mItemViewHeight = (int) (mItemViewWidth * 1.46f);//item的高
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
        return new RecyclerView.LayoutParams(RecyclerView.LayoutParams.WRAP_CONTENT,
                RecyclerView.LayoutParams.WRAP_CONTENT);
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (state.getItemCount() == 0 || state.isPreLayout()) return;
        removeAndRecycleAllViews(recycler);

        mItemViewWidth = (int) (getHorizontalSpace() * 0.87f);
        mItemViewHeight = (int) (mItemViewWidth * 1.46f);
        mItemCount = getItemCount();
        mScrollOffset = Math.min(Math.max(mItemViewHeight, mScrollOffset), mItemCount * mItemViewHeight);
        if (showLog) {
            Log.e(tag,"================= mItemViewHeight: "+mItemViewHeight);
        }
        layoutChild(recycler);
    }

    boolean isScroll = false;
    @Override
    public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {
        isScroll = true;
        if (showLog) {
//            Log.e(tag, "===================================== dy: "+dy+" dySum: "+dySum);
        }
        int pendingScrollOffset = mScrollOffset + dy;
        mScrollOffset = Math.min(Math.max(mItemViewHeight, mScrollOffset + dy), mItemCount * mItemViewHeight);
        layoutChild(recycler);
        return mScrollOffset - pendingScrollOffset + dy;
    }


    @Override
    public boolean canScrollVertically() {
        return true;
    }

    @Override
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) {
//        super.smoothScrollToPosition(recyclerView, state, position);
            RecyclerView.SmoothScroller smoothScroller = new CenterSmoothScroller(recyclerView.getContext());
            smoothScroller.setTargetPosition(position);
            startSmoothScroll(smoothScroller);
    }

    private static class CenterSmoothScroller extends LinearSmoothScroller {

        public CenterSmoothScroller(Context context) {
            super(context);
        }

        @Override
        public int calculateDtToFit(int viewStart, int viewEnd, int boxStart, int boxEnd, int snapPreference) {
            return (boxStart + (boxEnd - boxStart) / 2) - (viewStart + (viewEnd - viewStart) / 2);
        }

        @Override
        protected float calculateSpeedPerPixel(DisplayMetrics displayMetrics) {
            return 100f / displayMetrics.densityDpi;
        }
    }
    public static int bottomItemVisibleHeight;
    public static int bottomItemPosition;
    public static boolean isSlide = false;
    private void layoutChild(RecyclerView.Recycler recycler) {
        if (getItemCount() == 0 ) return;
        if (isSlide) return;  //如果是滑动就禁止

        bottomItemPosition = (int) Math.floor(mScrollOffset / mItemViewHeight);
        if (showLog) {
            Log.e(tag, "[======= bottomItemPosition: "+bottomItemPosition);
        }
        if (isScroll) {
            if (showLog) {
                Log.e(tag, "[======= isScroll");
            }
//            getChildAt(bottomItemPosition);
//            startRotation(getChildAt(bottomItemPosition));
//            if (!isFlep) {
//                animView = getChildAt(bottomItemPosition);
//                startRotation90();
//            }
        }
        int remainSpace = getVerticalSpace() - mItemViewHeight;

//        int bottomItemVisibleHeight = mScrollOffset % mItemViewHeight;
        bottomItemVisibleHeight = mScrollOffset % mItemViewHeight;
        final float offsetPercentRelativeToItemView = bottomItemVisibleHeight * 1.0f / mItemViewHeight;

        if (showLog) {
            Log.e(tag,"layoutChild =============================start bottomItemVisibleHeight: "+bottomItemVisibleHeight+" remainSpace: "+remainSpace);
        }

        ArrayList<ItemViewInfo> layoutInfos = new ArrayList<>();
        for (int i = bottomItemPosition - 1, j = 1; i >= 0; i--, j++) {
            double maxOffset = (getVerticalSpace() - mItemViewHeight) / 2 * Math.pow(0.8, j);
            int start = (int) (remainSpace - offsetPercentRelativeToItemView * maxOffset);
            float scaleXY = (float) (Math.pow(mScale, j - 1) * (1 - offsetPercentRelativeToItemView * (1 - mScale)));
            float positonOffset = offsetPercentRelativeToItemView;
            float layoutPercent = start * 1.0f / getVerticalSpace();
            if (showLog) {
                Log.e(tag,"============== start: "+(start+100)+" scaleXY： "+scaleXY+" positonOffset: "+positonOffset+" layoutPercent: "+layoutPercent+" i: "+i);
            }
            ItemViewInfo info = new ItemViewInfo(start, scaleXY, positonOffset, layoutPercent);
            layoutInfos.add(0, info);
            remainSpace = (int) (remainSpace - maxOffset);
            if (remainSpace <= 0) { //滑动到顶部触发
                if (showLog) {
                    Log.e(tag, "=============== remainSpace<=0 remainSpace: "+remainSpace);
                }
                info.setTop((int) (remainSpace + maxOffset+10));
                info.setPositionOffset(0);
                info.setLayoutPercent(info.getTop() / getVerticalSpace());
                info.setScaleXY((float) Math.pow(mScale, j - 1));
                break;
            }
        }

        if (showLog) {
            Log.e(tag,"layoutChild =============================end");
        }

        if (bottomItemPosition < mItemCount) {
            final int start = getVerticalSpace() - bottomItemVisibleHeight;
            layoutInfos.add(new ItemViewInfo(start, 1.0f, bottomItemVisibleHeight * 1.0f / mItemViewHeight, start * 1.0f / getVerticalSpace())
                    .setIsBottom());
        } else {
            bottomItemPosition = bottomItemPosition - 1;//99
        }

        int layoutCount = layoutInfos.size();
        final int startPos = bottomItemPosition - (layoutCount - 1);
        final int endPos = bottomItemPosition;
        final int childCount = getChildCount();
        for (int i = childCount - 1; i >= 0; i--) {
            View childView = getChildAt(i);
            int pos = getPosition(childView);
            if (pos > endPos || pos < startPos) {
                removeAndRecycleView(childView, recycler);
            }
        }

        detachAndScrapAttachedViews(recycler);

        for (int i = 0; i < layoutCount; i++) {
            View view = recycler.getViewForPosition(startPos + i);
            ItemViewInfo layoutInfo = layoutInfos.get(i);
            addView(view);
            measureChildWithExactlySize(view);
            int left = (getHorizontalSpace() - mItemViewWidth) / 2;
            layoutDecoratedWithMargins(view, left, layoutInfo.getTop(), left + mItemViewWidth, layoutInfo.getTop() + mItemViewHeight);
            view.setPivotX(view.getWidth() / 2);
            view.setPivotY(0);
            view.setScaleX(layoutInfo.getScaleXY());
            view.setScaleY(layoutInfo.getScaleXY());
        }

//        animView = getChildAt(bottomItemPosition);
//        int top = animView.getTop();
//        Log.e(tag, "============== animView top: "+animView.getTop()+" bottomItemPosition: "+bottomItemPosition);
//        if (top>=490 && !isFlep) {
//            startRotation90();
//        }

    }

    /**
     * 测量itemview的确切大小
     */
    private void measureChildWithExactlySize(View child ) {
        final int widthSpec = View.MeasureSpec.makeMeasureSpec(mItemViewWidth, View.MeasureSpec.EXACTLY);
        final int heightSpec = View.MeasureSpec.makeMeasureSpec(mItemViewHeight, View.MeasureSpec.EXACTLY);
        child.measure(widthSpec, heightSpec);
    }

    /**
     * 获取RecyclerView的显示高度
     */
    public int getVerticalSpace() {
        return getHeight() - getPaddingTop() - getPaddingBottom();
    }

    /**
     * 获取RecyclerView的显示宽度
     */
    public int getHorizontalSpace() {
        return getWidth() - getPaddingLeft() - getPaddingRight();
    }


    float rotation;
    CountDownTimer countDownTimer;
    boolean isFlep = false;
    private void startRotation90(){
        isFlep = true;
        countDownTimer =  new CountDownTimer(2000,100){

            @Override
            public void onTick(long l) {
                startRotation(animView,10);
            }

            @Override
            public void onFinish() {
                rotation = 0;
            }
        }.start();
    }

    private void startRotation(View view, float moveFlex){
        Log.i(this.getClass().getName(),"22222222222222222222222222222moveFlex=="+moveFlex);
        if(rotation>=90){
            isFlep = false;
            if(countDownTimer!=null){
                countDownTimer.cancel();
            }
            view.setRotationX(-90);  //开始旋转
            if(animationEndListener!=null){
                animationEndListener.onAnimationEnd();
            }
            return;
        }
        if(moveFlex<20){
            rotation = rotation + 1;
        }else if(moveFlex<40){
            rotation = rotation + 2;
        }else if(moveFlex>40){
            rotation = rotation + 3;
        }


        view.setPivotX(this.getWidth()/2); //View旋转中心点的X坐标
        view.setPivotY(this.getHeight()/2);

        int distance = 16000;
        float scale = mContext.getResources().getDisplayMetrics().density * distance;
        view.setCameraDistance(scale);   //设置镜头视角

        if(rotation>90){
            rotation = 90;
        }
        view.setRotationX(-rotation);  //开始旋转
    }

    public AnimationEndListener animationEndListener;

    public interface AnimationEndListener {
        void onAnimationEnd();
    }

    public void setOnAnimationEndListener(AnimationEndListener animationEndListener){
        this.animationEndListener = animationEndListener;
    }
}

